home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Graphics / picsize / picsize.c < prev    next >
C/C++ Source or Header  |  2000-04-21  |  9KB  |  311 lines

  1. /* :ts=3
  2. ** PicSize - determines picture size, depth and format
  3. **
  4. ** written & © Ralph Reuchlein <amiga@rripley.de> 1999
  5. */
  6.  
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdarg.h>
  11.  
  12. #include <exec/types.h>
  13. #include <proto/exec.h>
  14. #include <proto/dos.h>
  15. #include <proto/datatypes.h>
  16. #include <proto/iffparse.h>
  17. #include <datatypes/pictureclass.h>
  18. #include <exec/memory.h>
  19.  
  20. const UBYTE ver_string[] = "$VER: Picsize 1.2 (26.12.99)Copyright © 1999 by Ralph Reuchlein";
  21.  
  22.  
  23. /* ReadArgs defines ----------------------------------------------- */
  24. #define ARGS_TEMPLATE   "FILE/A,"\
  25.                         "FORMAT=FMT,"\
  26.                         "INTRODUCER=INTR/K"
  27.  
  28. enum {
  29.    OPT_FILE = 0,
  30.    OPT_FMT,
  31.    OPT_INTR,
  32.  
  33.    OPT_COUNT
  34. };
  35. LONG args[OPT_COUNT];
  36.  
  37. #define ARG_FILE  ((STRPTR)args[OPT_FILE])
  38. #define ARG_FMT   ((STRPTR)args[OPT_FMT])
  39. #define ARG_INTR  ((STRPTR)args[OPT_INTR])
  40.  
  41. #define DEFAULT_FORMAT        "%f: %wx%hx%d [%t,%s bytes]"
  42. #define DEFAULT_INTRODUCER    '%'
  43.  
  44.  
  45. /* Prototypes ----------------------------------------------------- */
  46. void     error(STRPTR,...);
  47. STRPTR   dupstr(STRPTR);
  48. void     freestr(STRPTR);
  49. BPTR     testFile(STRPTR);
  50. void     printFmt(STRPTR,struct BitMapHeader *,struct DataType *,BPTR);
  51.  
  52.  
  53.  
  54. /* Global variables ----------------------------------------------- */
  55.  
  56. BOOL  fileOk=FALSE;
  57. ULONG fileSize=0;
  58. #define FILENAMESIZE 512
  59. UBYTE fileName[FILENAMESIZE];
  60. int   errReturnValue=0;
  61.  
  62.  
  63. /* ---------------------------------------------------------------- */
  64. int main(UWORD argc,STRPTR argv[]) {
  65.    struct RDArgs *rdargs;
  66.    Object        *picobj;
  67.    BPTR           fl;
  68.  
  69.    /* process arguments */
  70.    if (rdargs=ReadArgs(ARGS_TEMPLATE,args,NULL)) {
  71.       /* test if we really have a file */
  72.       if (fl=testFile(ARG_FILE)) {
  73.          /* we now create new DataType object ... */
  74.          if (picobj=NewDTObject(ARG_FILE,TAG_DONE))
  75.          {
  76.             /* get all information we need */
  77.             struct BitMapHeader *bmhdr;
  78.             struct DataType     *dt;
  79.             ULONG                id;
  80.             GetDTAttrs(picobj,DTA_DataType,&dt,TAG_DONE);
  81.             id = dt->dtn_Header->dth_GroupID;
  82.             /* ... which must be a still picture */
  83.             if (id == GID_PICTURE) {
  84.                SetDTAttrs(picobj,NULL,NULL,PDTA_FreeSourceBitMap,TRUE,TAG_DONE);
  85.                GetDTAttrs(picobj,PDTA_BitMapHeader,&bmhdr,TAG_DONE);
  86.  
  87.                /* make formatted output */
  88.                if (ARG_FMT) {
  89.                   printFmt(ARG_FMT,bmhdr,dt,fl);
  90.                }
  91.                else {
  92.                   STRPTR fmt=dupstr(DEFAULT_FORMAT);
  93.                   printFmt(fmt,bmhdr,dt,fl);
  94.                   freestr(fmt);
  95.                }
  96.             }
  97.             else {
  98.                error("%s: File is not of type '%s' (but is '%s')!\n",ARG_FILE,GetDTString(GID_PICTURE),GetDTString(id));
  99.             }
  100.             /* dipose DataType object */
  101.             DisposeDTObject(picobj);
  102.          }
  103.          else {
  104.             long err=IoErr();
  105.             error("%s: Couldn't create DataType object, Error %i: ",ARG_FILE,err);
  106.             PrintFault(err,"");
  107.             error("\n");
  108.          }
  109.          UnLock(fl);
  110.       }
  111.       FreeArgs(rdargs);
  112.    }
  113.    else {
  114.       error("Usage: %s %s\n",argv[0],ARGS_TEMPLATE);
  115.    }
  116.    return errReturnValue;
  117. }
  118.  
  119.  
  120.  
  121. /* ---------------------------------------------------------------- */
  122. void error(STRPTR fmt,...) {
  123.    va_list args;
  124.    va_start(args,fmt);
  125.    vfprintf(stdout,fmt,args);
  126.    va_end(args);
  127.    errReturnValue=1;
  128. }
  129.  
  130.  
  131. STRPTR dupstr(STRPTR src) {
  132.    STRPTR dup=(STRPTR)AllocVec(strlen(src)+1,MEMF_PUBLIC|MEMF_REVERSE);
  133.    if (dup) {
  134.       strcpy(dup,src);
  135.       return dup;
  136.    }
  137.    error("Couldn't allocate %u bytes memory for dupstr()\n",strlen(src)+1);
  138.    return NULL;
  139. }
  140.  
  141. void freestr(STRPTR dup) {
  142.    if (dup) FreeVec(dup);
  143. }
  144.  
  145.  
  146. /* ---------------------------------------------------------------- */
  147. BPTR testFile(STRPTR filename) {
  148.    BOOL ok=FALSE;
  149.    BPTR l=NULL;
  150.    struct FileInfoBlock *fib=AllocDosObject(DOS_FIB,NULL);
  151.    if (fib) {
  152.       /* lock the file */
  153.       if (l=Lock(filename,ACCESS_READ)) {
  154.          /* examine file */
  155.          if (Examine(l,fib)) {
  156.             /* test for file */
  157.             switch(fib->fib_DirEntryType) {
  158.                case ST_SOFTLINK:       /* dangerous, because SOFTLINK can point to a directory */
  159.                case ST_LINKFILE:
  160.                case ST_FILE:
  161.                   fileOk   = TRUE;                    /* stored global */
  162.                   fileSize = (ULONG)fib->fib_Size;    /* stored global */
  163.                   ok=TRUE;
  164.                   break;
  165.                default:
  166.                   break;
  167.             }
  168.          }
  169.          else {
  170.             error("%s: Couldn't examine file information!\n",filename);
  171.          }
  172.       }
  173.       else {
  174.          error("%s: Couldn't access to this file (maybe not found?)!\n",filename);
  175.       }
  176.       FreeDosObject(DOS_FIB,fib);
  177.    }
  178.    else {
  179.       error("%s: Couldn't allocate FileInfoBlock memory!\n",filename);
  180.    }
  181.    if (ok) {
  182.       /* we return the file lock if ok */
  183.       return l;
  184.    }
  185.    else {
  186.       if (l) UnLock(l);
  187.    }
  188.    return NULL;
  189. }
  190.  
  191.  
  192.  
  193. /* ---------------------------------------------------------------- */
  194. #define FMT_STRING      's'
  195. #define FMT_INTEGER     'i'
  196.  
  197. void printFmt(STRPTR fmt,struct BitMapHeader *bmhd,struct DataType *dt,BPTR lock) {
  198.    register int tmp0,tmp1,intr;
  199.    STRPTR   fmt_end = fmt + strlen(fmt),tmp_fmt,str2;
  200.  
  201.    /* if there is no format, return */
  202.    if (!fmt) return;
  203.  
  204.    /* determine full filename */
  205.    if (!NameFromLock(lock,fileName,FILENAMESIZE)) {
  206.       error("Couldn't examine full filename!\n");
  207.       return;
  208.    }
  209.  
  210.    /* do we have specified a special introducer? */
  211.    if (ARG_INTR) {
  212.       intr = *ARG_INTR;    /* only the first character */
  213.    }
  214.    else {
  215.       intr = DEFAULT_INTRODUCER;
  216.    }
  217.  
  218.    /* we process the format string: replace the format types by
  219.       C-format types and process the format portion one by one */
  220.    tmp_fmt=fmt;
  221.    while(fmt<fmt_end) {
  222.       tmp_fmt=fmt;
  223.       /* search for the introducer */
  224.       while ((*fmt!=intr) && (fmt<fmt_end)) fmt++; if (fmt>=fmt_end) break;
  225.       /* write string til introducer */
  226.       *fmt=0; fputs(tmp_fmt,stdout); *fmt='%';     /* fprintf() only uses '%'! */
  227.       tmp_fmt=fmt;
  228.       /* search for the terminating format type character */
  229.       while ((!isalpha(*fmt)) && (fmt<fmt_end)) fmt++; if (fmt>=fmt_end) break;
  230.       tmp0 = *fmt; tmp1=*(fmt+1);
  231.       switch (tmp0) {
  232.          case 'n':      /* basename of file */
  233.             *fmt=FMT_STRING; *(fmt+1)=0;
  234.             fprintf(stdout,tmp_fmt,FilePart(fileName));
  235.             fmt++; *fmt=tmp1;
  236.             break;
  237.          case 'f':      /* full name of file */
  238.             *fmt=FMT_STRING; *(fmt+1)=0;
  239.             fprintf(stdout,tmp_fmt,fileName);
  240.             fmt++; *fmt=tmp1;
  241.             break;
  242.          case 'P':      /* path name of file including trailing / and : */
  243.             *fmt=FMT_STRING; *(fmt+1)=0;
  244.             str2=FilePart(fileName); tmp0=*str2; *str2=0;
  245.             fprintf(stdout,tmp_fmt,fileName);
  246.             *str2=tmp0;
  247.             fmt++; *fmt=tmp1;
  248.             break;
  249.          case 'p':      /* path name of file excluding trailing / */
  250.             *fmt=FMT_STRING; *(fmt+1)=0;
  251.             str2=PathPart(fileName); tmp0=*str2; *str2=0;
  252.             fprintf(stdout,tmp_fmt,fileName);
  253.             *str2=tmp0;
  254.             fmt++; *fmt=tmp1;
  255.             break;
  256.          case 'o':      /* basename without suffix of file */
  257.             *fmt=FMT_STRING; *(fmt+1)=0;
  258.             str2=fileName+strlen(fileName);
  259.             while ((*str2!='.') && (str2>fileName)) str2--;
  260.             if (*str2=='.')   { *str2=0; } else { str2=NULL; }
  261.             fprintf(stdout,tmp_fmt,FilePart(fileName));
  262.             if (str2) *str2='.';
  263.             fmt++; *fmt=tmp1;
  264.             break;
  265.          case 'e':      /* suffix/extension of file */
  266.             *fmt=FMT_STRING; *(fmt+1)=0;
  267.             str2=fileName+strlen(fileName);
  268.             while ((*str2!='.') && (str2>fileName)) str2--;
  269.             if (*str2=='.')   fprintf(stdout,tmp_fmt,str2);
  270.             fmt++; *fmt=tmp1;
  271.             break;
  272.          case 'w':      /* width of image */
  273.             *fmt=FMT_INTEGER; *(fmt+1)=0;
  274.             fprintf(stdout,tmp_fmt,bmhd->bmh_Width);
  275.             fmt++; *fmt=tmp1;
  276.             break;
  277.          case 'h':      /* height of image */
  278.             *fmt=FMT_INTEGER; *(fmt+1)=0;
  279.             fprintf(stdout,tmp_fmt,bmhd->bmh_Height);
  280.             fmt++; *fmt=tmp1;
  281.             break;
  282.          case 'd':      /* depth of image */
  283.             *fmt=FMT_INTEGER; *(fmt+1)=0;
  284.             fprintf(stdout,tmp_fmt,bmhd->bmh_Depth);
  285.             fmt++; *fmt=tmp1;
  286.             break;
  287.          case 't':      /* image format/type */
  288.             *fmt=FMT_STRING; *(fmt+1)=0;
  289.             fprintf(stdout,tmp_fmt,dt->dtn_Header->dth_Name);
  290.             fmt++; *fmt=tmp1;
  291.             break;
  292.          case 's':      /* image file size */
  293.             *fmt=FMT_INTEGER; *(fmt+1)=0;
  294.             fprintf(stdout,tmp_fmt,fileSize);
  295.             fmt++; *fmt=tmp1;
  296.             break;
  297.          default:
  298.             *(fmt+1)=0;
  299.             fputs(tmp_fmt,stdout);
  300.             fmt++; *fmt=tmp1;
  301.       }
  302.       tmp_fmt=fmt;
  303.    }
  304.    if (tmp_fmt<fmt) {
  305.       fputs(tmp_fmt,stdout);
  306.    }
  307.    fputc('\n',stdout);
  308. }
  309.  
  310.  
  311.